/*
 * Antonio: Clase Action esqueleto para la gestion basica de los medicamentos:
 * creacion, modificacion, eliminacion y listado
 */
package infb.actions;

import org.apache.struts.action.*;
import javax.servlet.http.*;
import infb.dao.*;
import infb.modelo.*;
import infb.errores.*;
import infb.forms.*;
import javax.naming.*;
import java.util.*;
import infb.util.*;
import java.util.List;
import java.util.ArrayList;

public class GestionMedicamentosAction extends Action {

    /*
     * Metodo interno destinado a la creacion de medicamentos
     */
    private ActionForward verMedicamento(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException, NamingException {
        try {
            Context contexto = new InitialContext();
            MedicamentosInterfaz iMedicamento = (MedicamentosInterfaz) contexto.lookup("MedicamentosEJB");
            Long idMedicamento = new Long(peticion.getParameter("id"));
            Medicamentos medicamento = iMedicamento.find(idMedicamento);

            if (medicamento == null) {
                throw new GestionHospitalariaException("Error: El identificador del medicamento pasado como parámetro no existe");
            }

            // Incorporamos el bean en la sesion
            peticion.setAttribute("medicamento", medicamento);

            return mapping.findForward("ok");
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO MedicamentosInterfaz " + ne.getMessage());
        } catch (NumberFormatException nfe) {
            throw new GestionHospitalariaException("Error: El identificador del medicamentos debe ser un cadena " + nfe.getMessage());
        }
    }

    /*
     * Metodo previo al registro de un medicamento
     */
    private ActionForward prepararInsercion(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException {
        try {
            Context contexto = new InitialContext();

            // Recuperamos la sesion, para cargar en ella la lista con las categorias
            HttpSession sesion = peticion.getSession();
            // Cargamos la lista de categorias de medicamentos
            CategoriasMedicamentosInterfaz categoriasInterfaz = (CategoriasMedicamentosInterfaz) contexto.lookup("CategoriasMedicamentosEJB");
            List listaCategorias = categoriasInterfaz.findAll();
            sesion.setAttribute("listaCategorias", listaCategorias);
            sesion.removeAttribute("objetoModificar");

            return mapping.findForward("preparar_insercion_ok");
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO CategoriasMedicamentosInterfaz: " + ne.getMessage());
        }
    }

    private ActionForward cargarMedicamentos(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException {
        try {
            Context contexto = new InitialContext();
            MedicamentosInterfaz medicamentos = (MedicamentosInterfaz) contexto.lookup("MedicamentosEJB");
            Long idMedicamento = new Long(peticion.getParameter("id"));
            Medicamentos medicamento = medicamentos.find(idMedicamento);
            if (medicamento == null) {
                throw new GestionHospitalariaException("Error: El identificador del medicamento pasado como parámetro no existe");
            }

            // Recuperamos la sesion
            HttpSession sesion = peticion.getSession();

            // Cargamos la lista de categorias de medicamentos
            CategoriasMedicamentosInterfaz categoriasInterfaz = (CategoriasMedicamentosInterfaz) contexto.lookup("CategoriasMedicamentosEJB");
            List listaCategorias = categoriasInterfaz.findAll();
            sesion.setAttribute("listaCategorias", listaCategorias);

            // Incorporamos el bean en la sesion
            sesion.setAttribute("objetoModificar", medicamento);

            // Redirigimos hacia la vista
            return mapping.findForward("cargar_ok");
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO MedicamentosInterfaz " + ne.getMessage());
        } catch (NumberFormatException nfe) {
            throw new GestionHospitalariaException("Error: El identificador del medicamento debe ser un numero " + nfe.getMessage());
        }
    }

    /*
     * Metodo interno destinado a la insercion de medicamentos
     */
    private ActionForward insertarMedicamentos(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException {
        try {
            Context contexto = new InitialContext();
            MedicamentosInterfaz medicamentos = (MedicamentosInterfaz) contexto.lookup("MedicamentosEJB");
            CategoriasMedicamentosInterfaz categorias = (CategoriasMedicamentosInterfaz) contexto.lookup("CategoriasMedicamentosEJB");
            SetMedicamentosForm formularioDatos = (SetMedicamentosForm) form;

            // Si el medicamento no esta registrado previamente (no violamos la AK de la tabla Medicamentos),
            // se procede para insertarlo
            if (!medicamentos.estaRegistrado(formularioDatos.getNombre())) {
                Medicamentos medicamento = new Medicamentos();
                medicamento.setNombre(formularioDatos.getNombre());
                medicamento.setCategoria(categorias.findByNombre(formularioDatos.getCategoria()));
                medicamento.setDefinicion(formularioDatos.getDefinicion());
                medicamento.setComposicion(formularioDatos.getComposicion());
                medicamento.setPosologia(formularioDatos.getPosologia());
                medicamento.setInteracciones(formularioDatos.getInteracciones());
                medicamento.setEfectosSecundarios(formularioDatos.getEfectosSecundarios());
                medicamento.setObservaciones(formularioDatos.getObservaciones());

                medicamentos.create(medicamento);
                peticion.setAttribute("mensaje", "El medicamento ha sido insertado correctamente");
                peticion.setAttribute("urlRetorno", "index.jsp");

                return mapping.findForward("ok");
            } else {
                // El medicamento ya existia en la base de datos
                peticion.setAttribute("claveMensajeError", "formularios.set_medicamentos.errores.nombre.repetido");
                peticion.setAttribute("urlRetorno", "NuevosMedicamentos.do");

                return mapping.findForward("error");
            }
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO MedicamentosInterfaz " + ne.getMessage());
        } catch (Exception e) {
            throw new GestionHospitalariaException("Error: No se pudo insertar correctamente el medicamento en la Base de Datos " + e.getMessage());
        }
    }

    /*
     * Metodo interno destinado a la modificacion de medicamentos
     */
    private ActionForward modificarMedicamentos(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException {
        try {
            Context contexto = new InitialContext();
            MedicamentosInterfaz medicamentos = (MedicamentosInterfaz) contexto.lookup("MedicamentosEJB");
            CategoriasMedicamentosInterfaz categorias = (CategoriasMedicamentosInterfaz) contexto.lookup("CategoriasMedicamentosEJB");
            SetMedicamentosForm formularioDatos = (SetMedicamentosForm) form;

            HttpSession sesion = peticion.getSession();
            Medicamentos medicamento = medicamentos.find(((Medicamentos) sesion.getAttribute("objetoModificar")).getId());

            // Comprobamos que no queremos actualizar el nombre de nuestro medicamento, por el de uno
            // previamente registrado en la base de datos
            Medicamentos medicamentoCargado = (Medicamentos) sesion.getAttribute("objetoModificar");
            if ((!medicamentos.estaRegistrado(formularioDatos.getNombre()) && !formularioDatos.getNombre().equalsIgnoreCase(medicamentoCargado.getNombre())) || (formularioDatos.getNombre().equalsIgnoreCase(medicamentoCargado.getNombre()))) {
                medicamento.setNombre(formularioDatos.getNombre());
                medicamento.setCategoria(categorias.findByNombre(formularioDatos.getCategoria()));
                medicamento.setDefinicion(formularioDatos.getDefinicion());
                medicamento.setComposicion(formularioDatos.getComposicion());
                medicamento.setPosologia(formularioDatos.getPosologia());
                medicamento.setInteracciones(formularioDatos.getInteracciones());
                medicamento.setEfectosSecundarios(formularioDatos.getEfectosSecundarios());
                medicamento.setObservaciones(formularioDatos.getObservaciones());

                medicamentos.edit(medicamento);
                sesion.removeAttribute("objetoModificar");
                peticion.setAttribute("mensaje", "El medicamento ha sido modificado correctamente");
                peticion.setAttribute("urlRetorno", "ListarMedicamentos.do");

                return mapping.findForward("ok");
            } else {
                // El nombre del medicamento que queremos utilizar ya exisitia previamente
                peticion.setAttribute("claveMensajeError", "formularios.set_medicamentos.errores.nombre.repetido");
                peticion.setAttribute("urlRetorno", "ListarMedicamentos.do");

                return mapping.findForward("error");
            }
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO MedicamentosInterfaz " + ne.getMessage());
        } catch (Exception e) {
            throw new GestionHospitalariaException("Error: No se pudo modificar correctamente el medicamento en la Base de Datos " + e.getMessage());
        }
    }

    /*
     * Metodo interno destinado a la eliminacion de medicamentos
     */
    private ActionForward eliminarMedicamentos(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException {
        try {
            Context contexto = new InitialContext();
            MedicamentosInterfaz medicamentos = (MedicamentosInterfaz) contexto.lookup("MedicamentosEJB");

            //HttpSession sesion=peticion.getSession();
            //Medicamentos medicamento=medicamentos.find(((Medicamentos)sesion.getAttribute("objetoModificar")).getId());

            Medicamentos medicamento;

            String[] arrayNombres = peticion.getParameterValues("id");
            List listaNombres = new ArrayList();
            listaNombres = arrayToList(arrayNombres);

            for (int i = 0; i < listaNombres.size(); i++) {
                //  System.out.print(Long.getLong((String)listaNombres.get(i)));
                Long med = Long.valueOf((String) listaNombres.get(i));
                medicamento = medicamentos.find(med);
                medicamentos.remove(medicamento);
            }
            /*medicamentos.remove(medicamento);
            sesion.removeAttribute("objetoModificar");
            peticion.setAttribute("mensaje","El medicamento ha sido eliminado correctamente");
            peticion.setAttribute("urlRetorno","index.jsp");*/

            return mapping.findForward("ok");
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO MedicamentosInterfaz " + ne.getMessage());
        } catch (Exception e) {
            throw new GestionHospitalariaException("Error: No se pudo eliminar correctamente el medicamento de la Base de Datos " + e.getMessage());
        }
    }

    /*
     * Metodo interno destinado al listado de medicamentos
     */
    private ActionForward listarMedicamentos(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException {

        try {
            Context contexto = new InitialContext();
            MedicamentosInterfaz medicamentoInterfaz = (MedicamentosInterfaz) contexto.lookup("MedicamentosEJB");

            Paginador p = new Paginador(medicamentoInterfaz.findAll(), peticion);
            List listaMedicamentos = p.getResultadosPaginados();
            String[] arrayNombres = peticion.getParameterValues("nombre");
            List listaNombres = arrayToList(arrayNombres);

            // Si se encontraron medicamentos los incorporamos con beans a la peticion
            // para que esten disponibles en el fichero .jsp
            if (listaMedicamentos != null) {
                peticion.setAttribute("lista_nombres", listaNombres);
                peticion.setAttribute("lista_medicamentos", listaMedicamentos);
                peticion.setAttribute("navegacion", p.getNavegacion());
                peticion.setAttribute("informacion", p.getMetaInformacion());
            }
            return mapping.findForward("listar_ok");
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO MedicamentosInterfaz " + ne.getMessage());
        }
    }

    /*
     * Metodo interno destinado al listado de medicamentos
     */
    private ActionForward buscarMedicamentos(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException {

        try {
            Context contexto = new InitialContext();
            MedicamentosInterfaz medicamentoInterfaz = (MedicamentosInterfaz) contexto.lookup("MedicamentosEJB");

            // Recuperamos la sesion, para cargar en ella la lista con las categorias
            HttpSession sesion = peticion.getSession();
            // Cargamos la lista de categorias de medicamentos
            CategoriasMedicamentosInterfaz categoriasInterfaz = (CategoriasMedicamentosInterfaz) contexto.lookup("CategoriasMedicamentosEJB");
            List listaCategorias = categoriasInterfaz.findAll();
            sesion.setAttribute("listaCategorias", listaCategorias);

            String buscar = peticion.getParameter("buscar");
            if (buscar != null && buscar.equals("1")) {
                // Obtenemos los parametros de busqueda
                BuscarMedicamentosForm formularioBusqueda = (BuscarMedicamentosForm) form;
                String nombre = formularioBusqueda.getNombre();
                String categoria = formularioBusqueda.getCategoria();

                // Almacenamos el resultado de la consulta en la peticion
                Paginador p = new Paginador(medicamentoInterfaz.busquedaAvanzada(nombre, categoria), peticion);
                List listaMedicamentos = p.getResultadosPaginados();
                if (listaMedicamentos != null) {
                    peticion.setAttribute("lista_medicamentos", listaMedicamentos);
                    peticion.setAttribute("navegacion", p.getNavegacion());
                    peticion.setAttribute("informacion", p.getMetaInformacion());
                }
            }

            return mapping.findForward("buscar_ok");
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar alguna de las clases DAO implicadas en el metodo " + ne.getMessage());
        }
    }

    /*
     * ------------------------------
     * Metodo Principal de la Clase
     * ------------------------------
     */
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException, NamingException {
        String delegaEn = mapping.getParameter();
        if (delegaEn.equalsIgnoreCase("preparar_insercion")) {
            // codigo para crear un medicamento
            return this.prepararInsercion(mapping, form, peticion, respuesta);
        } else if (delegaEn.equalsIgnoreCase("cargar")) {
            // cargar los datos de un medicamento
            return this.cargarMedicamentos(mapping, form, peticion, respuesta);
        } else if (delegaEn.equalsIgnoreCase("insertar")) {
            // insertar un medicamento
            return this.insertarMedicamentos(mapping, form, peticion, respuesta);
        } else if (delegaEn.equalsIgnoreCase("modificar")) {
            // modificar un medicamento
            return this.modificarMedicamentos(mapping, form, peticion, respuesta);
        } else if (delegaEn.equalsIgnoreCase("eliminar")) {
            // borrar un medicamento
            return this.eliminarMedicamentos(mapping, form, peticion, respuesta);
        } else if (delegaEn.equalsIgnoreCase("ver")) {
            // ver un medicamento
            return this.verMedicamento(mapping, form, peticion, respuesta);
        } else if (delegaEn.equalsIgnoreCase("listar")) {
            // listar medicamentos
            return this.listarMedicamentos(mapping, form, peticion, respuesta);
        } else {
            return this.buscarMedicamentos(mapping, form, peticion, respuesta);
        }
    }

    /*
     * Metodo privado auxiliar
     */
    private <T> List<T> arrayToList(T[] array) {
        List lista = new ArrayList<T>();
        if (array != null) {
            for (int i = 0; i < array.length; i++) {
                lista.add(array[i]);
            }
        }
        return lista;
    }
}

